//
//  UserRequest.swift
//  Employee
//
//  Created by swordjoy on 2017/3/16.
//  Copyright © 2017年 remotevillage. All rights reserved.
//

import Foundation
import SwiftyJSON
import Moya
import iVersion

var Refresh_Token_Error = "1017"

struct UserRequest: LoginResultProtocol, DataResultProtocol {
  
  static let shared = UserRequest()
  
  func login(with loginModel: LoginModel, loginSuccess: @escaping VoidClosure, failure: VoidClosure? = nil) -> Cancellable? {
    
    guard LogHelper.verifyUsername(with: loginModel.username) else {
        failure?()
        return nil
    }
    guard LogHelper.verifyPassword(with: loginModel.password) else {
        failure?()
        return nil
    }
    
    // 如果请求cache里面有该请求,直接返回
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }

    let cancle = UserProvider.request(UserAPI.login(username: loginModel.username, password: loginModel.password)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.loginProtocol(with: result, loginSuccess: { (data) in
        let access_token = data["access_token"].stringValue
        let refresh_token = data["refresh_token"].stringValue
        
        // 保存token
        Token.shared.cacheToken(token: access_token, refreshToken: refresh_token)
        // 通过token请求用户信息
        UserRequest.shared.getUserInfo(loginSuccess: loginSuccess, failure: failure)
        Account.userAccount = loginModel.username
      }, loginFailure: failure)
     
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    
    return cancle
  }
  

    /// 这里不可能出现多次点击和token失效,不判断
    func getUserInfo(loginSuccess: @escaping VoidClosure, failure: VoidClosure? = nil) {
        UserProvider.request(UserAPI.getUserInfo()) { (result) in
            self.dataProtocol(with: result, isHideHUD: false, success: { (data) in
                // 保存用户信息
                User.save(with: data)
                
                loginSuccess()
                Account.isLogin = true
                if !Account.isSetPushAlias { UserRequest.shared.setPushAlias() }
            }, failure: failure)
        }
    }
  
  func refreshToken(success: @escaping VoidClosure) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.refreshToken()) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      switch result {
      case let .success(response):
        let json = JSON(data: response.data)
        let responseCode = json["responseCode"].stringValue
        
        if Refresh_Token_Error == responseCode {
            User.logoutClean()
            User.longTimeNotLogin()
            return
        }
        if responseCode == "1003" {
            Token.shared.cacheToken(token: json["data"]["access_token"].stringValue, refreshToken: json["data"]["refresh_token"].stringValue)
            success()
        }
        
      case let .failure(error):
        SJApp.log(error)
        SJToast.show("未知错误")
      }
      
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  
  func getUserAddressBook(success: @escaping ([ChatUser]) -> Void) -> Cancellable {
  
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle =  UserProvider.request(UserAPI.getUserAddressBook()) { (result) in
      
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (data) in
        
        let chatUsers = ChatUser.array(from: data["elements"].arrayValue)
        success(chatUsers)
        
      }, overdue: { 
        
        let _ = UserRequest.shared.getUserAddressBook(success: success)
        
      }, failure: nil)
      
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    
    return cancle
    
  }
  
  func logout(success: @escaping VoidClosure) -> Cancellable {
    
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.logout()) { (result) in
      
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (data) in
        
          success()
        
      }, overdue: {  let _ = UserRequest.shared.logout(success: success) }, failure: nil)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    
    return cancle
    
  }
  
  // MARK: - 获取修改密码验证码
  
  func getModifyPasswordCode(phone: String) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.getModifyPasswordCode(phone: phone)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (_) in }, failure: nil)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  // MARK: - 验证验证码
  
  func verifyCode(phone: String, code: String, success: @escaping VoidClosure) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.verifyCode(phone: phone, code: code)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (_) in
        success()
      }, failure: nil)
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  // MARK: - 重置验证码
  
  func resetPassword(phone: String, password: String, success: @escaping VoidClosure) -> Cancellable {
    let requestKey = SJApp.functionKey()
    if let cacheCancle = GlobalConfig.requestCache[requestKey] { return cacheCancle }
    
    let cancle = UserProvider.request(UserAPI.resetPassword(phone: phone, password: password)) { (result) in
      GlobalConfig.requestCache.removeValue(forKey: requestKey)
      
      self.dataProtocol(with: result, success: { (_) in
        success()
      }, failure: nil)
      
    }
    
    GlobalConfig.requestCache[requestKey] = cancle
    return cancle
  }
  
  func setPushAlias() {
    JPUSHService.registrationIDCompletionHandler({ (errorCode, registrationID) in
        guard let temp = registrationID else {
            Account.isSetPushAlias = false
            return
        }
        UserProvider.request(UserAPI.setPushAlias()) { (result) in
            self.dataProtocol(with: result, success: { (_) in
                let tags = Set.init(User.tags)
                
                JPUSHService.setTags(tags, alias: temp, fetchCompletionHandle: { (code, set, alias) in
                    if code == 0 {
                        Account.isSetPushAlias = true
                        SJApp.log("\(code) + \(String(describing: set)) + \(String(describing: alias))")
                    }
                })
                
            }, failure: nil)
        }
    })
  }
    func versionApplication() {
        let requestKey = SJApp.functionKey()
        if GlobalConfig.requestCache[requestKey] != nil { return }
        let _ = UserProvider.request(UserAPI.getVersion) { (result) in
            GlobalConfig.requestCache.removeValue(forKey: requestKey)
            
            func checkVersion(forcedUpdate: Bool) {
                if Reachability.forInternetConnection().currentReachabilityStatus() == ReachableViaWiFi || forcedUpdate {
                    let iver = iVersion.sharedInstance()
                    iver?.applicationBundleID = Bundle.main.bundleIdentifier
                    if forcedUpdate {
                        iver?.updatePriority = .high
                    } else {
                        iver?.updatePriority = .medium
                    }
                }
                
            }
            
            self.dataProtocol(with: result, success: { (data) in
                let forcedUpdate = data["forcedUpdate"].boolValue
                let notice = data["notice"].boolValue
                
                UserDefaults.standard.set(forcedUpdate, forKey: "versionForcedUpdate")
                UserDefaults.standard.set(notice, forKey: "versionNotice")
                
                if notice {
                    checkVersion(forcedUpdate: forcedUpdate)
                }
                
                
            }, failure: {
                
                let forcedUpdate: Bool = (UserDefaults.standard.object(forKey: "versionForcedUpdate") != nil)
                
                if let n = UserDefaults.standard.object(forKey: "versionNotice") {
                    if (n as? Bool)! {
                        checkVersion(forcedUpdate: forcedUpdate)
                    }
                } else {
                    checkVersion(forcedUpdate: forcedUpdate)
                }
            })
        }
        
    }
}
